
var path = require('path');
var express = require('express');
var uuid = require('node-uuid');
var bodyParser = require('body-parser');
var url = require('url');
var fs    = require('fs');
var https = require('https');
var http = require('http');
var format = require('string-format');
format.extend(String.prototype);
var request = require('request');
var urlencode = require('urlencode');
var common = require("./common");

class TWebSvr{
    constructor(){
        this.objs={
            app: null , 
            server: null
        };
        this.config={
            port:20036,
            domain:"wss.hhdata.cn",
            https:{
                enable:true ,
                keyFn:"D:/gitee/hhudev/svr/keys/4195813_wss.hhdata.cn.key",
                certFn:"D:/gitee/hhudev/svr/keys/4195813_wss.hhdata.cn.pem"
            }
        };
        this.statics = {
            "/":"D:/gitee/hhudev/web"
        };
        this.routes={
            common:{
                default:{
                    hello:function(result , request , response){
                        if(!result){
                            result = {
                                error: null ,
                                data:""
                            };
                        }
                        result.data ="hello . hhu dev.";
                        response.send(JSON.stringify(result));
                    },
                    errHandler:function(result , request , response){
                        if( !result || result==null){
                            result={};
                        }
                        result.error = "api path is error.";
                        response.send(JSON.stringify(result));
                    }
                }
            }
        }
    }
    registRoute( appId , module , action , handler){
        if( !this.routes[appId]){
            this.routes[appId]={}
        }
        if( !this.routes[appId][module]){
            this.routes[appId][module] ={}
        }
        this.routes[appId][module][action] = handler;
    }
    getHandler( appId , module , action ){
        var me = this;
        var handler = me.routes.common.default.errHandler;
        if( me.routes[appId] && 
            me.routes[appId][module] && 
            me.routes[appId][module][action]){
                handler = me.routes[appId][module][action];
            }
        return handler;
    }
    start(callback){
        var me = this;
        try{
            var app = express();
            /*
            * 静态虚拟目录
            * */
            for (var sp in me.statics) {
                var webPath = me.statics[sp];
                app.use(sp, express.static(webPath));
            }
            /*
            * 动态路由
            * */
            var urlencodedParser = bodyParser.urlencoded({extended: false});
            app.use(urlencodedParser);
            app.use(bodyParser.json());
            var jsonParser = bodyParser.json();
            var apiPath ="/:appId/:module/:action";
            app.all(apiPath, jsonParser, function (req, res) {
                try{
                    var appId = req.params.appId;
                    var module = req.params.module;
                    var action = req.params.action;
                    var handler = me.getHandler(appId , module , action);
                    
                    res.header("Access-Control-Allow-Origin", "*");
                    res.header("Access-Control-Allow-Headers", "content-type");
                    res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
                    var ps = common.TComm.extend({}, req.query);
                    var result = {
                        appId: appId ,
                        module: module ,
                        action:action ,
                        ps: ps,
                        error: null,
                        result: null
                    };

                    
                    if (req.method == "POST" ) {
                        if( req.headers["content-type"].indexOf('application/json')>=0 ){
                            ps = common.TComm.extend(ps, req.body);
                            handler( result , req , res);
                        }
                        else {
                            req.setEncoding('utf8');
                            req.on('data', function (data) {
                                try {
                                    var obj = JSON.parse(data);
                                    ps = extend(ps, obj);
                                } catch (ee) {
                                    console.log(ee)
                                }
                            });
                            req.on('end', function () {
                                handler( result , req , res);
                            });
                        }
                    } else if (req.method == "GET") {
                        handler( result , req , res);
                    }else if (req.method == "OPTIONS") {
                        res.setHeader('Access-Control-Allow-Headers','Content-Type,Access-Control-Allow-Headers,Authorization,X-Requested-With');
                        res.send(200);
                    }
                }
                catch(erHandler){
                    console.log(erHandler);
                    res.send(400);
                }
            });
 
            var options = {};
            try{
                if( me.config.https.enable){
                    options = {
                        key: fs.readFileSync(me.config.https.keyFn),
                        cert: fs.readFileSync(me.config.https.certFn)
                    };
                }
            }
            catch(eer){
                console.log(eer);
            }
            
            var webServer = me.config.https.enable? https.createServer(options, app):  http.createServer(options, app);

            webServer.listen(me.config.port, function (err) {
                me.objs.app  = app;
                me.objs.server = webServer;
                var msg = "start web server on :{protocol}://{domain}:{port}/<appId>/<module>/<action>";
                msg = msg.format({
                    protocol: me.config.https.enable?"https":"http" ,
                    port: me.config.port ,
                    domain: me.config.domain
                })
                console.log( msg);
                common.TComm.cb(callback);
            }); 
        }
        catch (e) {
            console.log(e);
        }
    }
}

module.exports = {
    TWebSvr:TWebSvr
}
